package xxx.xxxxx.template.resolver;

import graphql.ErrorType;
import graphql.ExceptionWhileDataFetching;
import graphql.GraphQLError;
import graphql.kickstart.execution.error.GenericGraphQLError;
import graphql.kickstart.execution.error.GraphQLErrorHandler;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
public class GraphqlExceptionHandler implements GraphQLErrorHandler {
    static class CodedGraphQLError extends GenericGraphQLError {

        private HttpStatus httpStatus;

        public CodedGraphQLError(HttpStatus httpStatus, String message) {
            super(message);
            this.httpStatus = httpStatus;
        }

        public int getCode() {
            return httpStatus.value();
        }

        public String getReason() {
            return httpStatus.getReasonPhrase();
        }
    }

    @Override
    public List<GraphQLError> processErrors(List<GraphQLError> errors) {
        List<GraphQLError> errorList = new ArrayList<>();

        for (GraphQLError err : errors) {
            if (err.getErrorType() == ErrorType.DataFetchingException) {
                ExceptionWhileDataFetching exceptionWhileDataFetching = (ExceptionWhileDataFetching) err;
                Throwable exception = exceptionWhileDataFetching.getException();
                CodedGraphQLError codedError;
                if (exception instanceof RuntimeException) {
                    codedError = new CodedGraphQLError(HttpStatus.OK, exception.getMessage());
                } else {
                    codedError = new CodedGraphQLError(HttpStatus.INTERNAL_SERVER_ERROR, exception.getMessage());
                }
                errorList.add(codedError);
            } else {
                errorList.add(err);
            }
        }

        return errorList;
    }
}
